package com.dc.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dc.project.constant.ConstantCommon;
import com.dc.project.entity.bo.TaskFileCommitBo;
import com.dc.project.entity.map.TaskFileCommitMapVo;
import com.dc.project.entity.po.TaskFileCommit;
import com.dc.project.entity.query.TaskFileCommitQuery;
import com.dc.project.entity.vo.TaskFileCommitVo;
import com.dc.project.mapper.TaskFileCommitMapper;
import com.dc.project.service.TaskFileCommitService;
import com.dc.project.util.TaskCommitResolveUtil;
import com.dc.project.util.TaskSseEmitterUtil;
import com.own.business.resource.business.service.ResourceService;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.component.common.model.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * TaskFileCommitServiceImpl
 *
 * @author chenxueli
 * @date 2025-03-10 16:37:53
 */
@Slf4j
@Service
public class TaskFileCommitServiceImpl extends AbstractBaseService<
        TaskFileCommit,
        TaskFileCommitBo,
        TaskFileCommitVo,
        TaskFileCommitMapVo,
        TaskFileCommitQuery,
        TaskFileCommitMapper
        > implements TaskFileCommitService {

    @Resource
    private TaskFileCommitMapper taskFileCommitMapper;

    @Resource
    private ResourceService resourceService;

    @Resource
    private TaskCommitResolveUtil taskCommitResolveUtil;
    @Resource
    private TaskSseEmitterUtil taskSseEmitterUtil;

    /**
     * 新增数据之前
     *
     * @param commit po对象
     * @return 处理后的po对象
     */
    @Override
    public TaskFileCommit beforeAdd(TaskFileCommit commit) {
        // 添加的时候一定是未处理的
        commit.setStatus(TaskFileCommit.Status.WAITING);
        return super.beforeAdd(commit);
    }

    /**
     * 新增数据之后
     *
     * @param vo vo对象
     * @return 处理后的vo对象
     */
    @Override
    public TaskFileCommitVo afterAdd(TaskFileCommitVo vo) {
        // 开启处理任务
        taskCommitResolveUtil.start();
        return super.afterAdd(vo);
    }

    /**
     * 根据任务id查询所有提交的文件
     *
     * @param taskId 任务id
     * @return 提交的文件列表
     */
    @Override
    public List<TaskFileCommit> listByTaskId(Long taskId) {
        var wrapper = lambdaQueryWrapper().eq(TaskFileCommit::getFkTaskId, taskId);
        return listByWrapper(wrapper);
    }

    /**
     * 根据任务id查询所有提交的文件
     *
     * @param taskId   任务id
     * @param detailId 详情id
     * @param itemId   项目id
     * @return 提交的文件列表
     */
    @Override
    public List<TaskFileCommit> listByTaskId(Long taskId, Long detailId, Long itemId) {
        var commitList = new ArrayList<TaskFileCommit>();
        if (taskId != null) {
            var wrapper = lambdaQueryWrapper().eq(TaskFileCommit::getFkTargetId, taskId).eq(TaskFileCommit::getType, 1);
            commitList.addAll(listByWrapper(wrapper));
        }
        if (detailId != null) {
            var wrapper = lambdaQueryWrapper().eq(TaskFileCommit::getFkTargetId, detailId).eq(TaskFileCommit::getType, 2);
            commitList.addAll(listByWrapper(wrapper));
        }
        if (itemId != null) {
            var wrapper = lambdaQueryWrapper().eq(TaskFileCommit::getFkTargetId, itemId).eq(TaskFileCommit::getType, 3);
            commitList.addAll(listByWrapper(wrapper));
        }
        return commitList;
    }

    /**
     * 根据任务id查询可用的提交文件的结构体（用于大模型处理）
     *
     * @param taskId   任务id
     * @param detailId 详情id
     * @param itemId   项目id
     * @return 提交文件的结构体
     */
    @Override
    public List<TaskFileCommit.Structure> listAvailableStructureByTaskId(Long taskId, Long detailId, Long itemId) {
        var commitList = new ArrayList<TaskFileCommit>();
        if (taskId != null) {
            var wrapper = lambdaQueryWrapper()
                    .select(
                            TaskFileCommit::getId,
                            TaskFileCommit::getFilePath,
                            TaskFileCommit::getCompressMessage
                    )
                    .eq(TaskFileCommit::getFkTargetId, taskId)
                    .eq(TaskFileCommit::getStatus, TaskFileCommit.Status.PROCESSED)
                    .eq(TaskFileCommit::getType, 1);
            commitList.addAll(listByWrapper(wrapper));
        }
        if (detailId != null) {
            var wrapper = lambdaQueryWrapper()
                    .select(
                            TaskFileCommit::getId,
                            TaskFileCommit::getFilePath,
                            TaskFileCommit::getCompressMessage
                    )
                    .eq(TaskFileCommit::getFkTargetId, detailId)
                    .eq(TaskFileCommit::getStatus, TaskFileCommit.Status.PROCESSED)
                    .eq(TaskFileCommit::getType, 2);
            commitList.addAll(listByWrapper(wrapper));
        }
        if (itemId != null) {
            var wrapper = lambdaQueryWrapper()
                    .select(
                            TaskFileCommit::getId,
                            TaskFileCommit::getFilePath,
                            TaskFileCommit::getCompressMessage
                    )
                    .eq(TaskFileCommit::getFkTargetId, itemId)
                    .eq(TaskFileCommit::getStatus, TaskFileCommit.Status.PROCESSED)
                    .eq(TaskFileCommit::getType, 3);
            commitList.addAll(listByWrapper(wrapper));
        }
        return commitList
                .stream()
                .filter(item -> StringUtils.isNotBlank(item.getCompressMessage()))
                .map(TaskFileCommit::toStructure)
                .toList();
    }

    /**
     * 获取第一条未处理的提交信息
     *
     * @return 提交的文件信息
     */
    @Override
    public TaskFileCommit getFirstNotCompleteDetail() {
        var wrapper = lambdaQueryWrapper()
                .in(
                        TaskFileCommit::getStatus,
                        TaskFileCommit.Status.WAITING,
                        TaskFileCommit.Status.PARSING,
                        TaskFileCommit.Status.COMPRESSING
                )
                .orderByAsc(TaskFileCommit::getGmtCreate)
                .orderByAsc(TaskFileCommit::getId);
        return getOneByWrapper(wrapper);
    }

    /**
     * 修改状态
     *
     * @param id     任务详情id
     * @param status 状态
     */
    @Override
    public void updateStatus(Long id, int status) {
        var wrapper = new LambdaUpdateWrapper<TaskFileCommit>()
                .set(TaskFileCommit::getStatus, status)
                .eq(TaskFileCommit::getId, id);
        taskFileCommitMapper.update(wrapper);
    }

    /**
     * 修改解析后的文本内容
     *
     * @param id      任务详情id
     * @param content 内容
     */
    @Override
    public void updateParseMessage(Long id, String content) {
        var wrapper = new LambdaUpdateWrapper<TaskFileCommit>()
                .set(TaskFileCommit::getParseMessage, content)
                .eq(TaskFileCommit::getId, id);
        taskFileCommitMapper.update(wrapper);
    }

    /**
     * 修改压缩后的文本内容
     *
     * @param id      任务详情id
     * @param content 内容
     */
    @Override
    public void updateCompressMessage(Long id, String content) {
        var wrapper = new LambdaUpdateWrapper<TaskFileCommit>()
                .set(TaskFileCommit::getCompressMessage, content)
                .eq(TaskFileCommit::getId, id);
        taskFileCommitMapper.update(wrapper);
    }

    /**
     * 添加子文件列表到提交记录中
     *
     * @param parentCommit 父提交记录
     * @param subFileList  子文件列表
     */
    @Override
    public void putSubFileList(TaskFileCommit parentCommit, List<File> subFileList) {
        if (subFileList == null || subFileList.isEmpty()) {
            return;
        }
        for (int i = 0; i < subFileList.size(); i++) {
            var file = subFileList.get(i);
            // 执行上传
            var fileRecordVo = resourceService.upload(file);
            var commit = new TaskFileCommit();
            commit.setFkTaskId(parentCommit.getFkTaskId());
            commit.setFkDetailId(parentCommit.getFkDetailId());
            commit.setFkItemId(parentCommit.getFkItemId());
            commit.setFkParentCommitId(parentCommit.getId());
            commit.setType(parentCommit.getType());
            commit.setFkTargetId(parentCommit.getFkTargetId());
            commit.setStatus(TaskFileCommit.Status.WAITING);
            commit.setFilePath(fileRecordVo.getPosition() + fileRecordVo.getPath());
            commit.setFkFileId(fileRecordVo.getId());
            commit.setSortOrder(i);
            taskFileCommitMapper.insert(commit);
            // 推送数据信息
            taskSseEmitterUtil.send(
                    commit.getFkTaskId(),
                    ConstantCommon.SSE_EVENT.COMMIT_ADD_PARSE_STATUS,
                    () -> {
                        var vo = new TaskFileCommitVo(commit);
                        vo.setFileRecord(fileRecordVo);
                        return R.success(vo);
                    }
            );
        }
    }

    /**
     * 重新执行解析
     *
     * @param commitId 提交记录id
     */
    @Override
    public void reparse(Long commitId) {
        // 将任务设置为未解析
        updateStatus(commitId, TaskFileCommit.Status.WAITING);
        // 查询对应的提交记录
        var commit = getPoById(commitId);
        // 推送数据信息
        taskSseEmitterUtil.send(
                commit.getFkTaskId(),
                ConstantCommon.SSE_EVENT.COMMIT_PARSE_STATUS,
                () -> R.success(new TaskFileCommitVo(commit))
        );
        // 开启处理任务
        taskCommitResolveUtil.start();
    }

    /**
     * 验证父文件信息是否已经全部解析完成
     *
     * @param commitId 父提交记录id
     * @return true-完成，false-未完成
     */
    @Override
    public boolean checkSubComplete(Long commitId) {
        var wrapper = new LambdaQueryWrapper<TaskFileCommit>()
                .eq(TaskFileCommit::getFkParentCommitId, commitId)
                .in(
                        TaskFileCommit::getStatus,
                        TaskFileCommit.Status.WAITING,
                        TaskFileCommit.Status.PARSING,
                        TaskFileCommit.Status.COMPRESSING
                );
        return taskFileCommitMapper.selectCount(wrapper) == 0;
    }

    /**
     * 根据父提交记录id查询所有子提交记录
     *
     * @param commitId 父提交记录id
     * @return 子提交记录列表
     */
    @Override
    public List<TaskFileCommit> listByParentCommitId(Long commitId) {
        var wrapper = new LambdaQueryWrapper<TaskFileCommit>()
                .eq(TaskFileCommit::getFkParentCommitId, commitId)
                .orderByAsc(TaskFileCommit::getSortOrder);
        return taskFileCommitMapper.selectList(wrapper);
    }

    /**
     * 根据父提交记录id删除所有子提交记录
     *
     * @param parentCommitId 父提交记录id
     */
    @Override
    public void deleteByParentCommitId(Long parentCommitId) {
        // 查询出原有的提交文件信息
        var wrapper = new LambdaQueryWrapper<TaskFileCommit>()
                .eq(TaskFileCommit::getFkParentCommitId, parentCommitId);
        var commitList = taskFileCommitMapper.selectList(wrapper);
        taskFileCommitMapper.delete(wrapper);
        commitList.forEach(commit -> {
            taskSseEmitterUtil.send(
                    commit.getFkTaskId(),
                    ConstantCommon.SSE_EVENT.COMMIT_DELETE_FILE,
                    () -> R.success(new TaskFileCommitVo(commit))
            );
        });
    }

}
